#include "Managers/ChangeManager.h"
#include "Network/PackageManager.h"
#include "Subsystems/SubsystemTerrain.h"
#include "Utils/Utils.h"
#include "Log.h"
#include "Game/IInventory.hpp"
#include "Network/Packages/ComponentInventoryPackage.h"
#include "Network/Packages/SubsystemTerrainPackage.h"
#include "Network/Packages/PickablePackage.h"
#include "GameSingleton.h"

namespace PocketSurvival
{
    ChangeManager::ChangeManager() {}
    ChangeManager::~ChangeManager() {}

    void ChangeManager::loadGame()
    {
        m_terrain = GameSingleton::singletonPtr->getSingleton<SubsystemTerrain>();
    }

    void ChangeManager::update(float dt)
    {
        // 同步背包物品
        m_inventoryChangeLock.lock();
        if(m_inventoryChangeMap.size() > 0)
        {
            GameSingleton::packageManager->addSendPackageToQueue(std::make_shared<ComponentInventoryPackage>(m_inventoryChangeMap));
            m_inventoryChangeMap.clear();
        }
        m_inventoryChangeLock.unlock();

        // 同步地形
        m_terrainChanageMutex.lock();
        for(auto it = m_terrainChanageSet.begin(); it != m_terrainChanageSet.end(); ++it)
        {
            int32_t value = m_terrain->getCellValue(*it);
            std::shared_ptr<IPackage> package = std::make_shared<SubsystemTerrainPackage>(it->posX, it->posY, it->posZ, value);
            GameSingleton::packageManager->addSendPackageToQueue(package);
        }
        m_terrainChanageSet.clear();
        m_terrainChanageMutex.unlock();

        // 添加掉落物
        m_pickableCreativeMutex.lock();
        for(auto it = m_pickableCreativeVec.begin(); it != m_pickableCreativeVec.end(); ++it)
        {
            GameSingleton::packageManager->addSendPackageToQueue(std::make_shared<PickablePackage>(*it, PickablePackageType::Create));
        }
        m_pickableCreativeVec.clear();
        m_pickableCreativeMutex.unlock();
    }

    void ChangeManager::pickableCreative(Pickable *pickable)
    {
        m_pickableCreativeMutex.lock();
        m_pickableCreativeVec.push_back(pickable);
        m_pickableCreativeMutex.unlock();
    }

    void ChangeManager::inventoryChange(IInventory *inventory, int32_t slotIndex)
    {
        m_inventoryChangeLock.lock();
        auto it = m_inventoryChangeMap.find(inventory->id);
        if(it == m_inventoryChangeMap.end())
        {
            m_inventoryChangeMap[inventory->id] = std::set<int32_t>{ slotIndex };
        }
        else
        {
            it->second.insert(slotIndex);
        }
        m_inventoryChangeLock.unlock();
    }

    void ChangeManager::terrainChange(const Point3& point)
    {
        m_terrainChanageMutex.lock();
        m_terrainChanageSet.insert(point);
        m_terrainChanageMutex.unlock();
    }
    
} // namespace PocketSurvival
